--[[
	cargExplorer
]]

-- Now we can start with the code
cargExplorer = CreateFrame"Frame"

local GetMapZones = GetMapZones
local GetMapContinents = GetMapContinents
local GetCurrentMapContinent = GetCurrentMapContinent
local GetCurrentMapZone = GetCurrentMapZone
local GetAchievementNumCriteria = GetAchievementNumCriteria
local GetAchievementCriteriaInfo = GetAchievementCriteriaInfo

local zoneNr = {}
local contNr = #{GetMapContinents()}
for i=1, contNr do
	zoneNr[i] = #{GetMapZones(i)}
end

-- Helper functions
local function ColorGradient(perc, r1, g1, b1, r2, g2, b2, r3, g3, b3)
	if perc >= 1 then return r3, g3, b3 elseif perc <= 0 then return r1, g1, b1 end

	local segment, relperc = math.modf(perc*2)
	if segment == 1 then r1, g1, b1, r2, g2, b2 = r2, g2, b2, r3, g3, b3 end
	return r1 + (r2-r1)*relperc, g1 + (g2-g1)*relperc, b1 + (b2-b1)*relperc
end

-- Core functions
function cargExplorer:new()
	self.dataobj = LibStub("LibDataBroker-1.1"):NewDataObject("cargExplorer", {
		type = "data source",
		icon = "Interface\\Icons\\INV_Misc_Map02",
		text = "0% discovered",
		value = "0",
		suffix = " discovered",
		OnTooltipShow = self.OnTooltipShow
	})
	if(LibStub("cargMapDisplay")) then LibStub("cargMapDisplay"):RegisterObject("cargExplorer") end

	self:SetScript("OnEvent", self.UpdateMapDisplay)
	self:RegisterEvent"WORLD_MAP_UPDATE"
end

local lastMap
function cargExplorer:UpdateMapDisplay()
	local mapName = GetMapInfo()
	if(lastMap and mapName == lastMap) then return nil end
	
	lastMap = mapName
	local disc, total = self:GetExplorationInfo(mapName)

	if(total == 0) then disc, total = 1, 1 end
	local r, g, b = ColorGradient(disc/total, 1,0,0, 1,1,0, 0,1,0)
	local formattext = format("|c00%02x%02x%02x%.0f%%|r", r*255, g*255, b*255, disc/total*100)
	self.dataobj.text = formattext.." discovered"
	self.dataobj.value = formattext
end

local tableSort = function(a,b)
	if(a[2] and b[2]) then
		return a[2] > b[2]
	else
		return a[1] < b[1]
	end
end

function cargExplorer.OnTooltipShow(tooltip)
	local mapName = GetMapInfo()
	local disc, total, miss = cargExplorer:GetExplorationInfo(mapName, {})
	if(total == 0) then disc, total = 1, 1 end
	local r, g, b = ColorGradient(disc/total, 1,0,0, 1,1,0, 0,1,0)
	local formattext = format("|c00%02x%02x%02x%d/%d|r", r*255, g*255, b*255, disc, total)
	tooltip:AddLine(format(ERR_ZONE_EXPLORED, "|c00ff5050"..formattext.."|r"))
	if(total-disc > 0) then
		table.sort(miss, tableSort)
		for i, missing in pairs(miss) do
			if(i > 10) then break end
			if(missing[2]) then
				tooltip:AddDoubleLine(missing[1], missing[2], 1,1,1, 1,0.3,0.3)
			else
				tooltip:AddLine(missing[1], 1, 0.5, 0.5)
			end
		end
	end
end

function cargExplorer:GetExplorationInfo(name, miss)
	if(not name) then name = "World" end
	local achID = self.achIDs and self.achIDs[name]
	local disc, total = 0, 0

	if(achID) then
		total = GetAchievementNumCriteria(achID)
		if(select(4, GetAchievementInfo(achID))) then
			return total, total, miss
		elseif(total==0) then
			if(miss) then table.insert(miss, {name}) end
			return 0, 1, miss
		end

		for i=1, total do
			local name, critType, completed, _, _, _, _, assetID = GetAchievementCriteriaInfo(achID, i)
			if(completed) then
				disc = disc + 1
			else
				local missing
				if(critType == CRITERIA_TYPE_ACHIEVEMENT and assetID) then
					for j=1, GetAchievementNumCriteria(assetID) do
						if(not select(3, GetAchievementCriteriaInfo(assetID, j))) then
							missing = (missing or 0) + 1
						end
					end
				end
				if(miss) then table.insert(miss, {name, missing}) end
			end
		end
	end
	return disc, total, miss
end

cargExplorer:new()